/*
 * ReaderPlayer.cpp
 *
 *  Created on: 2018年5月6日
 *      Author: zhengboyuan
 */

#include "ReaderPlayer.h"
#include "TFileUtil.h"
#include "CLog.h"
#include "DateTime.h"
#include "ClockTime.h"

void ReaderPlayer::init()
{
	av::MediaRender::startup();
}

void ReaderPlayer::quit()
{
	av::MediaRender::cleanup();
}


ReaderPlayer::ReaderPlayer():
	m_reader(INVALID_READER),
	m_render()
{
	m_buffer.ensure(1024 * 1024 * 2);
}

ReaderPlayer::~ReaderPlayer()
{
	close();
}

bool ReaderPlayer::open(mreader_t reader, HWND hwnd)
{
	if (isRunning())
	{
		close();
	}

	if (!m_render)
	{
		m_render.reset(av::MediaRender::create(hwnd), av::MediaRender::destroy);
	}
	
	m_reader = reader;

	mreader_getFormat(m_reader, &m_format);

	m_render->open(m_format);
	m_render->play();

	if (m_format.vPropSize > 0)
	{
		//comn::FileUtil::write(m_format.vProp, m_format.vPropSize, "out.h264", false);

	}

	return true;
}

void ReaderPlayer::close()
{
	if (isRunning())
	{
		comn::Thread::stop();
	}

	closePlayer();

	m_reader = INVALID_READER;
}

bool ReaderPlayer::isOpen()
{
	return m_reader != INVALID_READER && (m_render->isOpen());
}

int ReaderPlayer::run()
{
	while (!m_canExit)
	{
		MPacket pkt;
		memset(&pkt, 0, sizeof(pkt));

		memset(m_buffer.data(), 0, m_buffer.capacity()-16);

		pkt.data = m_buffer.data();
		pkt.size = m_buffer.capacity();

		int rc = mreader_read(m_reader, &pkt);
		if (rc == 0)
		{
			//CLog::debug("mreader_read. type: %d, size: %5d, flags: %d, pts: %lld\n",
			//	pkt.type, pkt.size, pkt.flags, pkt.pts);

			if (pkt.type == MTYPE_VIDEO)
			{
				//comn::FileUtil::write(pkt.data, pkt.size, "out.h264", true);

				int64_t clock = comn::ClockTime::getTime() * 1000;
				int64_t pts = pkt.pts;
				util::TimestampChecker::Result lastResult;
				util::TimestampChecker::Result startResult;
				m_tsChecker.input(clock, pts, &lastResult, &startResult);

				int clockElapse = (int)lastResult.clockDiff / 1000;
				int offset = (int)startResult.offset / 1000;

				CLog::debug("ReaderPlayer checker. clock: %lld, pts: %lld, elapse: %d, offset: %d, \n", clock, pts, clockElapse, offset);

			}
			else
			{
				if (pkt.size > 1024 * 2)
				{
					assert(false);
				}
			}

			m_render->write(pkt);
		}
		else if (rc == EAGAIN)
		{
			mreader_wait(m_reader, 20);
		}
		else
		{
			mreader_wait(m_reader, 20);
		}
	}
	return 0;
}

void ReaderPlayer::doStop()
{
	mreader_interrupt(m_reader);
}

void ReaderPlayer::closePlayer()
{
	if (m_render)
	{
		m_render->stop();
		m_render->close();
	}
}

void ReaderPlayer::play()
{
	if (!m_render)
	{
		return;
	}

	m_tsChecker.reset();

	m_render->play();

}

void ReaderPlayer::pause()
{
	if (!m_render)
	{
		return;
	}

	m_render->pause();
}

void ReaderPlayer::stop()
{
	if (!m_render)
	{
		return;
	}

	m_render->stop();
}